package com.jh.fcsm.util.word;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

/**
 * @author xuyu
 * @Description: 使用POI, 进行Word相关的操作
 */
public class WordExport {
    private static final Logger logger = LoggerFactory.getLogger(WordExport.class);
    /**
     * 内部使用的文档对象
     **/
    private XWPFDocument document;

    private BookMarks bookMarks = null;

    /**
     * 功能描述:复制单元格，从source到target
     *
     * @param target
     * @param source
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void copyTableCell(XWPFTableCell target, XWPFTableCell source) {
        // 列属性
        if (source.getCTTc() != null) {
            target.getCTTc().setTcPr(source.getCTTc().getTcPr());
        }
        // 删除段落
        for (int pos = 0; pos < target.getParagraphs().size(); pos++) {
            target.removeParagraph(pos);
        }
        // 添加段落
        for (XWPFParagraph sp : source.getParagraphs()) {
            XWPFParagraph targetP = target.addParagraph();
            copyParagraph(targetP, sp);
        }
    }

    /**
     * 功能描述:复制段落，从source到target
     *
     * @param target
     * @param source
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void copyParagraph(XWPFParagraph target, XWPFParagraph source) {
        // 设置段落样式
        target.getCTP().setPPr(source.getCTP().getPPr());
        // 移除所有的run
        for (int pos = target.getRuns().size() - 1; pos >= 0; pos--) {
            target.removeRun(pos);
        }
        // copy 新的run
        for (XWPFRun s : source.getRuns()) {
            XWPFRun targetrun = target.createRun();
            copyRun(targetrun, s);
        }
    }

    /**
     * 功能描述:复制RUN，从source到target
     *
     * @param target
     * @param source
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void copyRun(XWPFRun target, XWPFRun source) {
        // 设置run属性
        target.getCTR().setRPr(source.getCTR().getRPr());
        // 设置文本
        target.setText(source.text());
    }

    /**
     * 功能描述:复制行，从source到target
     *
     * @param target
     * @param source
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void copyTableRow(XWPFTableRow target, XWPFTableRow source) {
        // 复制样式
        if (source.getCtRow() != null) {
            target.getCtRow().setTrPr(source.getCtRow().getTrPr());
        }
        // 复制单元格
        for (int i = 0; i < source.getTableCells().size(); i++) {
            XWPFTableCell cell1 = target.getCell(i);
            XWPFTableCell cell2 = source.getCell(i);
            if (cell1 == null) {
                cell1 = target.addNewTableCell();
            }
            copyTableCell(cell1, cell2);
        }
    }

    /**
     * ============= 页脚页码 end
     */

    public static void main(String[] args) throws Exception {
        WordExport wordExport = new WordExport();
        wordExport.setTemplate("C:\\Users\\Administrator\\Desktop\\合并封皮后.docx");
//        wordExport.addFooterPage();
        wordExport.simpleNumberFooter();
        wordExport.saveAs("C:\\Users\\Administrator\\Desktop\\merge11_" + UUID.randomUUID() + ".docx");
    }

    /**
     * @param templatePath 模板文件名称
     * @Description:为文档设置模板
     */
    public void setTemplate(String templatePath) {
        try {
            document = new CustomXWPFDocument(OPCPackage.open(templatePath));
            bookMarks = new BookMarks(document);
        } catch (Exception ex) {

        }
    }

    /**
     * @param indicator
     * @Description:进行标签替换的例子,传入的Map中，key表示标签名称，value是替换的信息
     */
    public void replaceBookMark(Map<String, String> indicator) {
        //循环进行替换
        Iterator<String> bookMarkIter = bookMarks.getNameIterator();
        while (bookMarkIter.hasNext()) {
            String bookMarkName = bookMarkIter.next();
            //得到标签名称
            BookMark bookMark = bookMarks.getBookmark(bookMarkName);
            //进行替换
            if (indicator.get(bookMarkName) != null) {
                bookMark.insertTextAtBookMark(indicator.get(bookMarkName), BookMark.INSERT_BEFORE);
            }
        }
    }

    /**
     * @param indicator
     * @Description:进行标签替换的例子,传入的Map中，key表示标签名称，value是替换的信息
     */
    public void replaceBookMark(Map<String, String> indicator, int replaceType) {
        //循环进行替换
        Iterator<String> bookMarkIter = bookMarks.getNameIterator();
        while (bookMarkIter.hasNext()) {
            String bookMarkName = bookMarkIter.next();
            //得到标签名称
            BookMark bookMark = bookMarks.getBookmark(bookMarkName);
            //进行替换
            if (indicator.get(bookMarkName) != null) {
                bookMark.insertTextAtBookMark(indicator.get(bookMarkName), replaceType);
            }
        }
    }

    public void replaceTableAtBookMark(String bookMarkName, List<Map<String, String>> mapList) {
        BookMark bookMark = bookMarks.getBookmark(bookMarkName);
        int rowNum = 0;

        XWPFTable table = bookMark.getContainerTable();
        XWPFTableRow row = bookMark.getContainerTableRow();
        rowNum = table.getRows().indexOf(row);

        //标签是否处于表格内
        if (bookMark.isInTable()) {
            // 如果没填充内容，填充空白
            if (null == mapList || mapList.size() == 0) {
                WordTablesUtils.fillBlankRow(row);
                return;
            }

            for (int i = 0; i < mapList.size() - 1; i++) {
                XWPFTableRow newRow = new XWPFTableRow((CTRow) row.getCtRow().copy(), table);
                Map<String, String> map = mapList.get(i + 1);
                rowNum++;
                WordTablesUtils.fillRow(newRow, map);
                table.addRow(newRow, rowNum);
            }

            WordTablesUtils.fillRow(row, mapList.get(0));
        }
    }

    /**
     * @param bookMarkName
     * @param content
     * @return void * @throws
     * @Description:书签处填充表格内容
     */
    public void fillTableAtBookMark(String bookMarkName, List<Map<String, String>> content) {
        //rowNum来比较标签在表格的哪一行
        int rowNum = 0;

        //首先得到标签
        BookMark bookMark = bookMarks.getBookmark(bookMarkName);
        Map<String, String> columnMap = new HashMap<String, String>();
        Map<String, Node> styleNode = new HashMap<String, Node>();

        //标签是否处于表格内
        if (bookMark.isInTable()) {

            //获得标签对应的Table对象和Row对象
            XWPFTable table = bookMark.getContainerTable();
            XWPFTableRow row = bookMark.getContainerTableRow();
            //			CTRow ctRow = row.getCtRow();
            List<XWPFTableCell> rowCell = row.getTableCells();
            for (int i = 0; i < rowCell.size(); i++) {
                columnMap.put(i + "", rowCell.get(i).getText().trim());
                //System.out.println(rowCell.get(i).getParagraphs().get(0).createRun().getFontSize());
                //System.out.println(rowCell.get(i).getParagraphs().get(0).getCTP());
                //System.out.println(rowCell.get(i).getParagraphs().get(0).getStyle());

                //获取该单元格段落的xml，得到根节点
                Node node1 = rowCell.get(i).getParagraphs().get(0).getCTP().getDomNode();

                //遍历根节点的所有子节点
                for (int x = 0; x < node1.getChildNodes().getLength(); x++) {
                    if (node1.getChildNodes().item(x).getNodeName().equals(BookMark.RUN_NODE_NAME)) {
                        Node node2 = node1.getChildNodes().item(x);

                        //遍历所有节点为"w:r"的所有自己点，找到节点名为"w:rPr"的节点
                        for (int y = 0; y < node2.getChildNodes().getLength(); y++) {
                            if (node2.getChildNodes().item(y).getNodeName().endsWith(BookMark.STYLE_NODE_NAME)) {

                                //将节点为"w:rPr"的节点(字体格式)存到HashMap中
                                styleNode.put(i + "", node2.getChildNodes().item(y));
                            }
                        }
                    } else {
                        continue;
                    }
                }
            }
            //循环对比，找到该行所处的位置，删除改行
            for (int i = 0; i < table.getNumberOfRows(); i++) {
                if (table.getRow(i).equals(row)) {
                    rowNum = i;
                    break;
                }
            }
            table.removeRow(rowNum);

            for (int i = 0; i < content.size(); i++) {
                //创建新的一行,单元格数是表的第一行的单元格数,
                //后面添加数据时，要判断单元格数是否一致
                XWPFTableRow tableRow = table.createRow();
                CTTrPr trPr = tableRow.getCtRow().addNewTrPr();
                CTHeight ht = trPr.addNewTrHeight();
                ht.setVal(BigInteger.valueOf(360));
            }

            //得到表格行数
            int rcount = table.getNumberOfRows();
            for (int i = rowNum; i < rcount; i++) {
                XWPFTableRow newRow = table.getRow(i);

                //判断newRow的单元格数是不是该书签所在行的单元格数
                if (newRow.getTableCells().size() != rowCell.size()) {

                    //计算newRow和书签所在行单元格数差的绝对值
                    //如果newRow的单元格数多于书签所在行的单元格数，不能通过此方法来处理，可以通过表格中文本的替换来完成
                    //如果newRow的单元格数少于书签所在行的单元格数，要将少的单元格补上
                    int sub = Math.abs(newRow.getTableCells().size() - rowCell.size());
                    //将缺少的单元格补上
                    for (int j = 0; j < sub; j++) {
                        newRow.addNewTableCell();
                    }
                }

                List<XWPFTableCell> cells = newRow.getTableCells();

                for (int j = 0; j < cells.size(); j++) {
                    XWPFParagraph para = cells.get(j).getParagraphs().get(0);
                    XWPFRun run = para.createRun();
                    if (content.get(i - rowNum).get(columnMap.get(j + "")) != null) {

                        //改变单元格的值，标题栏不用改变单元格的值
                        run.setText(content.get(i - rowNum).get(columnMap.get(j + "")) + "");

                        //将单元格段落的字体格式设为原来单元格的字体格式
                        run.getCTR().getDomNode().insertBefore(styleNode.get(j + "").cloneNode(true),
                                run.getCTR().getDomNode().getFirstChild());
                    }

                    para.setAlignment(ParagraphAlignment.CENTER);
                }
            }
        }
    }

    /**
     * 替换表格占位符
     *
     * @param param
     */
    public void replaceTableText(Map<String, Object> param) {
        try {
            //处理段落
            WordParagraphsUtils.replaceInAllParagraphs(document.getParagraphs(), param);
            //处理表格
            WordTablesUtils.replaceInTables(document.getTables(), param);
        } catch (Exception ex) {

        }
    }

    /**
     * 特殊处理
     *
     * @param param
     */
    public void replaceSpecialText(Map<String, Object> param) {
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            XmlCursor cursor = paragraph.getCTP().newCursor();
            cursor.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//*/w:txbxContent/w:p/w:r");

            List<XmlObject> ctrsintxtbx = new ArrayList<XmlObject>();

            while (cursor.hasNextSelection()) {
                cursor.toNextSelection();
                XmlObject obj = cursor.getObject();
                ctrsintxtbx.add(obj);
            }
            for (XmlObject obj : ctrsintxtbx) {
                CTR ctr = null;
                try {
                    ctr = CTR.Factory.parse(obj.xmlText());
                } catch (XmlException e) {
                    logger.error("特殊处理CTR异常");
                }
                //CTR ctr = CTR.Factory.parse(obj.newInputStream());
                XWPFRun bufferrun = new XWPFRun(ctr, (IRunBody) paragraph);
                String text = bufferrun.getText(0);
                if (text != null && param.containsKey(text)) {
                    text = text.replace(text, param.get(text) != null ? param.get(text).toString() : "");
                    bufferrun.setText(text, 0);
                }
                obj.set(bufferrun.getCTR());
            }
        }
    }

    /**
     * 替换表格占位符
     *
     * @param param
     */
    public void replaceParagraphsText(Map<String, Object> param) {
        try {
            //处理段落
            WordParagraphsUtils.replaceInAllParagraphs(document.getParagraphs(), param);
        } catch (Exception ex) {

        }
    }

    public void replaceText(Map<String, String> bookmarkMap, String bookMarkName) {
        //首先得到标签
        BookMark bookMark = bookMarks.getBookmark(bookMarkName);
        //获得书签标记的表格
        XWPFTable table = bookMark.getContainerTable();
        //获得所有的表
        //Iterator<XWPFTable> it = document.getTablesIterator();

        if (table != null) {
            //得到该表的所有行
            int rcount = table.getNumberOfRows();
            for (int i = 0; i < rcount; i++) {
                XWPFTableRow row = table.getRow(i);

                //获到改行的所有单元格
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell c : cells) {
                    for (Entry<String, String> e : bookmarkMap.entrySet()) {
                        if (c.getText().equals(e.getKey())) {
                            //删掉单元格内容
                            c.removeParagraph(0);
                            //给单元格赋值
                            c.setText(e.getValue());
                        }
                    }
                }
            }
        }
    }

    public void saveAs(String fileName) {
        File newFile = new File(fileName);
        try(FileOutputStream fos= new FileOutputStream(newFile)){
            this.document.write(fos);
            document.close();
        } catch (Exception e) {
            logger.error("保存文件异常");
        }
    }

    /**
     * @param bookMarkName
     * @param content
     * @return void * @throws
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @Description:书签处填充表格内容
     */
    public void fillTableAtBookMark(String bookMarkName, List<Map<String, String>> content, int rows) {
        // rowNum来比较标签在表格的哪一行
        int rowNum = 0;

        // 首先得到标签
        BookMark bookMark = bookMarks.getBookmark(bookMarkName);
        List<XWPFTableRow> rowsXWPFTableRow = new ArrayList<>(rows);
//        // 标签是否处于表格内
//        if (!bookMark.isInTable()) {
//            System.out.println("表格内");
//        }
        XWPFTable table = bookMark.getContainerTable();
        XWPFTableRow row = bookMark.getContainerTableRow();

        boolean isstart = false;
        int startcount = 0;
        for (int i = 0; i < table.getNumberOfRows(); i++) {
            if (table.getRow(i).equals(row)) {
                rowNum = i;
                isstart = true;
            }
            if (isstart) {
                rowsXWPFTableRow.add(table.getRow(i));
                startcount++;
            }
            if (startcount == rows) {
                break;
            }
        }
        int insertRowNum = rowNum + rows;
        for (int i = 0; i < content.size() - 1; i++) {
            for (XWPFTableRow newRow : rowsXWPFTableRow) {
                XWPFTableRow targetRow = table.insertNewTableRow(insertRowNum);
                copyTableRow(targetRow, newRow);
                insertRowNum++;
            }
        }

        int c = 0;
        for (Map<String, String> con : content) {
            for (int i = 0; i < rows; i++) {
                XWPFTableRow newRow = table.getRow(rowNum + c);
                c++;
                List<XWPFTableCell> cells = newRow.getTableCells();
                for (int j = 0; j < cells.size(); j++) {
                    if (con.get(cells.get(j).getText().trim()) != null) {
                        // 改变单元格的值，标题栏不用改变单元格的值
                        for (int k = cells.get(j).getParagraphs().get(0).getRuns().size() - 1; k > -1; k--) {
                            XWPFRun cellR = cells.get(j).getParagraphs().get(0).getRuns().get(k);
                            if (cellR.getText(cellR.getTextPosition()).equals(cells.get(j).getText().trim())) {
                                // 设置run属性
                                XWPFRun newcellR = cells.get(j).getParagraphs().get(0).createRun();
                                newcellR.getCTR().setRPr(cellR.getCTR().getRPr());
                                // 设置文本
                                newcellR.setText(con.get(cells.get(j).getText().trim()));
                                cells.get(j).getParagraphs().get(0).removeRun(k);
                            }
                        }
                    }
                }
            }
        }

    }

    /**
     * @param indicator
     * @Description:进行标签替换的例子,传入的Map中，key表示标签名称，value是替换的信息
     */
    public void replaceBookMarkBefore(Map<String, String> indicator) {
        // 循环进行替换
        Iterator<String> bookMarkIter = bookMarks.getNameIterator();
        while (bookMarkIter.hasNext()) {
            String bookMarkName = bookMarkIter.next();
            // 得到标签名称
            BookMark bookMark = bookMarks.getBookmark(bookMarkName);
            // 进行替换
            if (indicator.get(bookMarkName) != null) {
                bookMark.insertTextAtBookMark(indicator.get(bookMarkName), BookMark.INSERT_BEFORE);
            }
        }
    }

    // 删除所有的书签
    public void removeAllDocBookMark() {
        // List<XWPFParagraph> paraList = document.getParagraphs();
        // WordParagraphsUtils.removeParaListBookMark(paraList);
        //
        // List<XWPFTable> tableList = document.getTables();
        // if (tableList != null) {
        //     for (XWPFTable table : tableList) {
        //         List<XWPFTableRow> rowList = table.getRows();
        //         if (rowList != null) {
        //             for (XWPFTableRow row : rowList) {
        //                 List<XWPFTableCell> cellList = row.getTableCells();
        //                 if (cellList != null) {
        //                     for (XWPFTableCell cell : cellList) {
        //                         WordParagraphsUtils.removeParaListBookMark(cell.getParagraphs());
        //                     }
        //                 }
        //             }
        //         }
        //     }
        // }
    }

    /**
     * 多行替换
     *
     * @param bookMarkName
     * @param content
     * @param rows
     */
    public void replaceTableAtBookMark(String bookMarkName, List<Map<String, String>> content, int rows) {
        // rowNum来比较标签在表格的哪一行
        int rowNum = 0;

        // 首先得到标签
        BookMark bookMark = bookMarks.getBookmark(bookMarkName);
        List<XWPFTableRow> rowsXWPFTableRow = new ArrayList<>(rows);
//        // 标签是否处于表格内
//        if (!bookMark.isInTable()) {
//        }
        XWPFTable table = bookMark.getContainerTable();
        XWPFTableRow row = bookMark.getContainerTableRow();

        boolean isstart = false;
        int startcount = 0;
        for (int i = 0; i < table.getNumberOfRows(); i++) {
            if (table.getRow(i).equals(row)) {
                rowNum = i;
                isstart = true;
            }
            if (isstart) {
                rowsXWPFTableRow.add(table.getRow(i));
                startcount++;
            }
            if (startcount == rows) {
                break;
            }
        }
        int insertRowNum = rowNum + rows;
        for (int i = 0; i < content.size() - 1; i++) {
            for (XWPFTableRow newRow : rowsXWPFTableRow) {
                XWPFTableRow targetRow = table.insertNewTableRow(insertRowNum);
                copyTableRow(targetRow, newRow);
                insertRowNum++;
            }
        }

        int c = 0;
        for (Map<String, String> con : content) {
            for (int i = 0; i < rows; i++) {
                XWPFTableRow newRow = table.getRow(rowNum + c);
                c++;
                List<XWPFTableCell> cells = newRow.getTableCells();
                for (int j = 0; j < cells.size(); j++) {
                    for (XWPFTableCell cell : cells) {
                        List<XWPFParagraph> paragraphs = cell.getParagraphs();
                        try {
                            WordParagraphsUtils.replaceInAllParagraphs2(paragraphs, con);
                        } catch (Exception e) {
                            logger.error("多行替换异常");
                        }
                    }

                }
            }
        }
    }

    /**
     * 删除多行
     *
     * @param bookMarkName
     * @param rows
     */
    public void removeTableAtBookMark(String bookMarkName, int rows) {
        // rowNum来比较标签在表格的哪一行
        int rowNum = 0;

        // 首先得到标签
        BookMark bookMark = bookMarks.getBookmark(bookMarkName);
        List<XWPFTableRow> rowsXWPFTableRow = new ArrayList<>(rows);
//        // 标签是否处于表格内
//        if (!bookMark.isInTable()) {
//        }
        XWPFTable table = bookMark.getContainerTable();
        XWPFTableRow row = bookMark.getContainerTableRow();

        boolean isstart = false;
        int startcount = 0;
        for (int i = 0; i < table.getNumberOfRows(); i++) {
            if (table.getRow(i).equals(row)) {
                rowNum = i;
                isstart = true;
            }
            if (isstart) {
                rowsXWPFTableRow.add(table.getRow(i));
                startcount++;
            }
            if (startcount == rows) {
                break;
            }
        }
        for (int i = rowNum; i < rowNum + rows; i++) {
            table.removeRow(rowNum);
        }

    }

    /**
     * ============= 页脚页码
     */

    /**
     * 添加底部页码
     */
    public void addFooterPage() {
        // create footer
//        XWPFHeaderFooterPolicy policy = document.getHeaderFooterPolicy();
//        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
//        XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(document, sectPr);
//        CTP ctpFooter = CTP.Factory.newInstance();
//
//        XWPFParagraph[] parsFooter;
//
//        // add style (s.th.)
//        CTPPr ctppr = ctpFooter.addNewPPr();
//        CTString pst = ctppr.addNewPStyle();
//        pst.setVal("style21");
//        CTJc ctjc = ctppr.addNewJc();
//        ctjc.setVal(STJc.CENTER);
//        ctppr.addNewRPr();
//
//        CTR ctr = ctpFooter.addNewR();
//        ctr.addNewRPr();
//        CTFldChar fch = ctr.addNewFldChar();
//        fch.setFldCharType(STFldCharType.BEGIN);
//
//        ctr = ctpFooter.addNewR();
//        ctr.addNewInstrText().setStringValue(" PAGE ");
//
//        ctpFooter.addNewR().addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
//        ctpFooter.addNewR().addNewT().setStringValue("1");
//        ctpFooter.addNewR().addNewFldChar().setFldCharType(STFldCharType.END);
//
//        XWPFParagraph footerParagraph = new XWPFParagraph(ctpFooter, document);
//        parsFooter = new XWPFParagraph[1];
//        parsFooter[0] = footerParagraph;
//        policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, parsFooter);
        // 方法一
        XWPFFooter footer = document.createFooter(HeaderFooterType.DEFAULT);
        XWPFParagraph footerParagraph = footer.getParagraphArray(0);
        if (footerParagraph == null) {
            footerParagraph = footer.createParagraph();
        }
        footerParagraph.setAlignment(ParagraphAlignment.CENTER);
        footerParagraph.getCTP().addNewFldSimple().setInstr("PAGE \\* ARABIC MERGEFORMAT");
    }

    /**
     * @Description: 页脚:显示页码信息
     * 样式为底部居中 [第 X 页共 X]
     * https://blog.csdn.net/weixin_33969103/article/details/114304361
     * https://www.bbsmax.com/A/gAJGBPM8zZ/
     */
    public void simpleNumberFooter() throws Exception {
        CTP ctp = CTP.Factory.newInstance();
        XWPFParagraph codePara = new XWPFParagraph(ctp, document);
        XWPFRun r1 = codePara.createRun();
        r1.setText("第");
        setParagraphRunFontInfo(codePara, r1, null, "微软雅黑", "22");
        r1 = codePara.createRun();
        CTFldChar fldChar = r1.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.BEGIN);
        r1 = codePara.createRun();
        CTText ctText = r1.getCTR().addNewInstrText();
        ctText.setStringValue("PAGE \\* MERGEFORMAT");
        ctText.setSpace(SpaceAttribute.Space.PRESERVE);
        setParagraphRunFontInfo(codePara, r1, null, "微软雅黑", "22");
        fldChar = r1.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.END);
        r1 = codePara.createRun();
        r1.setText("页 共");
        setParagraphRunFontInfo(codePara, r1, null, "微软雅黑", "22");
        r1 = codePara.createRun();
        fldChar = r1.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.BEGIN);
        r1 = codePara.createRun();
        ctText = r1.getCTR().addNewInstrText();
        ctText.setStringValue("NUMPAGES \\* MERGEFORMAT ");
        ctText.setSpace(SpaceAttribute.Space.PRESERVE);
        setParagraphRunFontInfo(codePara, r1, null, "微软雅黑", "22");
        fldChar = r1.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.END);
        r1 = codePara.createRun();
//        r1.setText("页");
        setParagraphRunFontInfo(codePara, r1, null, "微软雅黑", "22");
        setParagraphAlignInfo(codePara, ParagraphAlignment.CENTER, TextAlignment.CENTER);
        codePara.setBorderTop(Borders.THICK);
        XWPFParagraph[] newparagraphs = new XWPFParagraph[1];
        newparagraphs[0] = codePara;
        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();

//        CTPageNumber pagetNumber = sectPr.addNewPgNumType();
//        pagetNumber.setStart(BigInteger.valueOf(1));

        XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(document, sectPr);
        headerFooterPolicy.createFooter(STHdrFtr.DEFAULT, newparagraphs);
    }

    /**
     * @Description 设置字体信息
     */
    public void setParagraphRunFontInfo(XWPFParagraph p, XWPFRun pRun, String content, String fontFamily, String fontSize) {
//        CTRPr pRpr = getRunCTRPr(p, pRun);
        if (StringUtils.isNotBlank(content)) {
            pRun.setText(content);
        }
    }

    /**
     * @Description: 得到XWPFRun的CTRPr
     */
    public CTRPr getRunCTRPr(XWPFParagraph p, XWPFRun pRun) {
        CTRPr pRpr = null;
        if (pRun.getCTR() != null) {
            pRpr = pRun.getCTR().getRPr();
            if (pRpr == null) {
                pRpr = pRun.getCTR().addNewRPr();
            }
        } else {
            pRpr = p.getCTP().addNewR().addNewRPr();
        }
        return pRpr;
    }

    /**
     * @Description: 设置段落对齐
     */
    public void setParagraphAlignInfo(XWPFParagraph p, ParagraphAlignment pAlign, TextAlignment valign) {
        if (pAlign != null) {
            p.setAlignment(pAlign);
        }
        if (valign != null) {
            p.setVerticalAlignment(valign);
        }
    }
}
